package ws

import (
	"sync"

	"gitee.com/crack007/goose/gslog"
)

func NewSessionManager() *SessionManager {
	return &SessionManager{
		sessionMap: make(map[int64]*Session),
	}
}

type SessionManager struct {
	sessionMap map[int64]*Session
	lock       sync.Mutex
}

func (x *SessionManager) addSession(session *Session) {
	x.lock.Lock()
	var closeSession *Session
	defer func() {
		x.lock.Unlock()
		gslog.Trace("[%d] AddSession-> remoteIp: %s count: %d", session.SessionId, session.RemoteIp, x.Count())
		if closeSession != nil {
			closeSession.Close()
		}
	}()

	if s, ok := x.sessionMap[session.SessionId]; ok {
		gslog.Debug("会话冲突 SessionId=%d", session.SessionId)
		// 出现会话冲突
		saveSession := s.sessionHandle.OnConflict(s, session)
		if s == saveSession {
			closeSession = session
		} else {
			closeSession = s
		}

		x.sessionMap[session.SessionId] = saveSession
		return
	}

	x.sessionMap[session.SessionId] = session
}

func (x *SessionManager) removeSession(session *Session) {
	x.lock.Lock()
	defer func() {
		x.lock.Unlock()
		gslog.Trace("[%d] RemoveSession-> remoteIp: %s count: %d", session.SessionId, session.RemoteIp, x.Count())
	}()

	delete(x.sessionMap, session.SessionId)
}

func (x *SessionManager) Count() int {
	return len(x.sessionMap)
}

func (x *SessionManager) GetById(sessionId int64) *Session {
	if s, ok := x.sessionMap[sessionId]; ok {
		return s
	}

	return nil
}

func (x *SessionManager) IterateSession(call func(session *Session)) {
	x.lock.Lock()
	defer x.lock.Unlock()
	for _, session := range x.sessionMap {
		call(session)
	}
}
